/**
 * 任务调度器
 * Task Scheduler
 */

const cron = require('node-cron');
const config = require('../config/config');
const logger = require('./logger');
const BackupService = require('../services/backup');

class TaskScheduler {
  constructor() {
    this.tasks = new Map();
    this.backupService = new BackupService();
  }

  /**
   * 启动调度器
   * Start scheduler
   */
  start() {
    logger.info('Starting task scheduler...');
    
    // 启动数据库备份任务
    this.scheduleBackupTask();
    
    // 启动清理任务
    this.scheduleCleanupTask();
    
    logger.info('Task scheduler started successfully');
  }

  /**
   * 停止调度器
   * Stop scheduler
   */
  stop() {
    logger.info('Stopping task scheduler...');
    
    for (const [name, task] of this.tasks) {
      if (task && typeof task.stop === 'function') {
        task.stop();
        logger.info(`Stopped task: ${name}`);
      }
    }
    
    this.tasks.clear();
    logger.info('Task scheduler stopped');
  }

  /**
   * 调度数据库备份任务
   * Schedule database backup task
   */
  scheduleBackupTask() {
    const schedule = config.backup.schedule || '0 2 * * *'; // 默认每天凌晨2点
    
    const task = cron.schedule(schedule, async () => {
      try {
        logger.info('Starting scheduled database backup...');
        const result = await this.backupService.performBackup();
        
        logger.info('Scheduled backup completed successfully', {
          fileName: result.backup.fileName,
          size: result.backup.size,
          deletedBackups: result.cleanup.deletedCount
        });
      } catch (error) {
        logger.error('Scheduled backup failed:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    task.start();
    this.tasks.set('database-backup', task);
    
    logger.info(`Database backup scheduled: ${schedule}`);
  }

  /**
   * 调度清理任务
   * Schedule cleanup task
   */
  scheduleCleanupTask() {
    // 每天凌晨3点执行清理任务
    const schedule = '0 3 * * *';
    
    const task = cron.schedule(schedule, async () => {
      try {
        logger.info('Starting scheduled cleanup task...');
        
        // 清理临时文件
        await this.cleanupTempFiles();
        
        // 清理过期会话
        await this.cleanupExpiredSessions();
        
        // 清理操作日志
        await this.cleanupOperationLogs();
        
        logger.info('Scheduled cleanup completed successfully');
      } catch (error) {
        logger.error('Scheduled cleanup failed:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    task.start();
    this.tasks.set('cleanup', task);
    
    logger.info(`Cleanup task scheduled: ${schedule}`);
  }

  /**
   * 清理临时文件
   * Clean temporary files
   */
  async cleanupTempFiles() {
    const fs = require('fs').promises;
    const path = require('path');
    
    try {
      const tempPath = config.upload.tempPath;
      const files = await fs.readdir(tempPath);
      
      let deletedCount = 0;
      let deletedSize = 0;
      
      for (const file of files) {
        const filePath = path.join(tempPath, file);
        const stats = await fs.stat(filePath);
        
        // 删除超过24小时的临时文件
        const ageHours = (Date.now() - stats.mtime.getTime()) / (1000 * 60 * 60);
        if (ageHours > 24) {
          await fs.unlink(filePath);
          deletedCount++;
          deletedSize += stats.size;
        }
      }
      
      if (deletedCount > 0) {
        logger.info(`Cleaned ${deletedCount} temporary files, freed ${this.formatFileSize(deletedSize)}`);
      }
    } catch (error) {
      logger.error('Failed to cleanup temporary files:', error);
    }
  }

  /**
   * 清理过期会话
   * Clean expired sessions
   */
  async cleanupExpiredSessions() {
    try {
      // 这里应该清理内存中的过期会话
      // 由于会话存储在内存中，这个功能需要在会话管理器中实现
      logger.info('Session cleanup completed');
    } catch (error) {
      logger.error('Failed to cleanup expired sessions:', error);
    }
  }

  /**
   * 清理操作日志
   * Clean operation logs
   */
  async cleanupOperationLogs() {
    const db = require('../database/connection');
    
    try {
      // 删除90天前的操作日志
      const result = await db.execute(
        'DELETE FROM operation_logs WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY)'
      );
      
      if (result[0].affectedRows > 0) {
        logger.info(`Cleaned ${result[0].affectedRows} old operation logs`);
      }
    } catch (error) {
      logger.error('Failed to cleanup operation logs:', error);
    }
  }

  /**
   * 手动执行备份
   * Manually execute backup
   */
  async executeBackup() {
    try {
      logger.info('Executing manual backup...');
      const result = await this.backupService.performBackup();
      
      logger.info('Manual backup completed successfully', {
        fileName: result.backup.fileName,
        size: result.backup.size
      });
      
      return result;
    } catch (error) {
      logger.error('Manual backup failed:', error);
      throw error;
    }
  }

  /**
   * 获取任务状态
   * Get task status
   */
  getTaskStatus() {
    const status = {};
    
    for (const [name, task] of this.tasks) {
      status[name] = {
        running: task && typeof task.running === 'boolean' ? task.running : true,
        nextRun: task && task.nextDate ? task.nextDate() : null
      };
    }
    
    return status;
  }

  /**
   * 格式化文件大小
   * Format file size
   */
  formatFileSize(bytes) {
    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;

    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }

    return `${size.toFixed(2)} ${units[unitIndex]}`;
  }
}

// 创建全局调度器实例
const scheduler = new TaskScheduler();

// 优雅关闭处理
process.on('SIGTERM', () => {
  logger.info('Received SIGTERM, stopping scheduler...');
  scheduler.stop();
  process.exit(0);
});

process.on('SIGINT', () => {
  logger.info('Received SIGINT, stopping scheduler...');
  scheduler.stop();
  process.exit(0);
});

module.exports = scheduler;